<?php

namespace App\Http\Controllers;

use App\Exceptions\UserExistsException;
use App\Exceptions\UserNotFoundException;
use App\Models\User;
use Sonata\GoogleAuthenticator\GoogleAuthenticator;
use Sonata\GoogleAuthenticator\GoogleQrUrl;

class UserController extends Controller
{
    /*
     * @api get /admin-api/a/users 用户列表
     * @version 0.0.1
     * @group admin
     *
     * @param query int [pageSize] 页数，默认15
     * @param query int [page] 页码，默认1
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{
     *    "total":10,
     *    "items":[]
     * }
     * }
     */
    public function index()
    {
        $this->validate($this->request, [
            "pageSize" => "integer|max:100|min:5",
            "page" => "integer|min:1"
        ]);
        $page = intval($this->request->input("page", 1));
        $pageSize = intval($this->request->input("pageSize", 15));
        $query = User::query();
        $total = $query->count();
        $usersObj = $query->orderBy('id', 'desc')->forPage($page, $pageSize)
            ->get();
        $items = [];
        if ($total) {
            /** @var User $userObj */
            foreach ($usersObj as $userObj) {
                $items[] = [
                    'id' => $userObj->getId(),
                    'name' => $userObj->getName(),
                    'mobile' => $userObj->getMobile(),
                    'role' => $userObj->getRoleName(),
                    'status' => $userObj->getStatus(),
                    'createdAt' => $userObj->getCreatedAt()->toDateTimeString()
                ];
            }
        }
        return $this->sendSuccessJson(['total'=>$total, 'items'=>$items]);
    }


    /*
     * @api post /admin-api/a/users 创建新用户
     * @version 0.0.1
     * @group admin
     *
     * @param body string name 姓名
     * @param body string mobile 手机号
     * @param body string password 密码
     * @param body int roleId 用户角色
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function store()
    {
        $this->validate($this->request, [
            'name' => 'required|string',
            'mobile' => 'required|regex:/^1[345789]\d{9}$/',
            'password' => 'required|alpha_dash|between:6,32',
            'roleId' => 'required|integer'
        ]);
        $name = $this->request->input('name');
        $mobile = $this->request->input('mobile');
        $password = $this->request->input('password');
        $roleId = $this->request->input('roleId');

        if (User::where('mobile', $mobile)->exists()) {
            throw new UserExistsException();
        }
        $googleAuth = new GoogleAuthenticator();
        $secret = $googleAuth->generateSecret();

        $userObj = new User();
        $userObj->setName($name);
        $userObj->setPassword($password);
        $userObj->setMobile($mobile);
        $userObj->setSecret($secret);
        $userObj->setRoleId($roleId);
        $userObj->save();
        $account = $mobile . '@' . config('app.host');
        $url = GoogleQrUrl::generate($account, $secret);
        return $this->sendSuccessJson($url);
    }

    /*
     * @api get /admin-api/a/users/{userId} 获取用户详情
     * @version 0.0.1
     * @group admin
     *
     * @param path int userId 用户ID
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function show($userId)
    {
        /** @var User $userObj */
        $userObj = $this->findOrThrowById($userId);
        $userInfo = [
            'id' => $userObj->getId(),
            'name' => $userObj->getName(),
            'mobile' => $userObj->getMobile(),
            'roleId' => $userObj->getRoleId()
        ];
        return $this->sendSuccessJson($userInfo);
    }

    /*
     * @api put /admin-api/a/users/{userId} 更新用户
     * @version 0.0.1
     * @group admin
     *
     * @param path int userId 用户ID
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function update($userId)
    {
        $this->validate($this->request, [
            'name' => 'required|string',
            'mobile' => 'required|regex:/^1[345789]\d{9}$/',
            'roleId' => 'required|integer'
        ]);
        $name = $this->request->input('name');
        $mobile = $this->request->input('mobile');
        $roleId = $this->request->input('roleId');
        /** @var User $userObj */
        $userObj = $this->findOrThrowById($userId);
        $userObj->setName($name);
        $userObj->setMobile($mobile);
        $userObj->setRoleId($roleId);
        $userObj->save();
        return $this->sendSuccessJson();
    }

    public function updateNonceSecret($userId)
    {
        /** @var User $userObj */
        $userObj = $this->findOrThrowById($userId);
        $googleAuth = new GoogleAuthenticator();
        $secret = $googleAuth->generateSecret();
        $account = $userObj->getMobile() . '@' . config('app.host');
        $data = [
            'url' => GoogleQrUrl::generate($account, $secret)
        ];
        return $this->sendSuccessJson($data);
    }

    public function getNonceQrUrl()
    {
        $mobile = '13823119307';
        $secret = 'ET7KDGUJUNQM37MB';
        $account = $mobile . '@' . config('app.host');
        $data = [
            'url' => GoogleQrUrl::generate($account, $secret)
        ];
        return $this->sendSuccessJson($data);
    }

    /*
     * @api put /admin-api/a/users/{userId}/password 重置用户密码
     * @version 0.0.1
     * @group admin
     *
     * @param path int userId 用户ID
     * @param body string password 密码
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function updatePassword($userId)
    {
        $this->validate($this->request, [
            'password' => 'required|alpha_dash|between:6,32',
        ]);
        $password = $this->request->input('password');
        /** @var User $userObj */
        $userObj = $this->findOrThrowById($userId);
        $userObj->setPassword($password);
        $userObj->save();
        return $this->sendSuccessJson();
    }

    /*
     * @api put /admin-api/a/users/{userId}/status 更新用户状态
     * @version 0.0.1
     * @group admin
     *
     * @param path int userId 用户ID
     * @param body string status 状态，0不可用，1可用
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function updateStatus($userId)
    {
        $this->validate($this->request, [
            'status' => 'required',
        ]);
        $status = $this->request->input('$status');
        /** @var User $userObj */
        $userObj = $this->findOrThrowById($userId);
        $userObj->setStatus($status);
        $userObj->save();
        return $this->sendSuccessJson();
    }

    private function findOrThrowById($userId)
    {
        $userObj = User::where('id', $userId)->first();
        if (empty($userObj)) {
            throw new UserNotFoundException();
        }
        return $userObj;
    }
}
